package club.kunlingou.dsc.common.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class HttpsClient {

	private final HttpURLConnection conn;

	private final String charset;

	private HttpsClient(HttpURLConnection conn, String charset) {
		
		this.conn = conn;
		this.charset = charset;
	}

	private static final SSLContext sslContext;

	private static final HostnameVerifier verifier;

	static {
		
		sslContext = getSSLContext();
		verifier = new HostnameVerifier() {
			@Override
			public boolean verify(String s, SSLSession sslSession) {
				return true;
			}
		};
	}

	private static SSLContext getSSLContext() {

		SSLContext sslContext;
		try {
			sslContext = SSLContext.getInstance("TLS");
			sslContext.init(null, new TrustManager[] { new X509TrustManager() {
				@Override
				public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				}

				@Override
				public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				}

				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return new X509Certificate[0];
				}
			} }, new SecureRandom());
		} catch (Exception e) {
			e.printStackTrace();
			sslContext = null;
		}
		return sslContext;
	}

	public static HttpsClient configure(String resquestUrl) throws Exception {
		
		return configure(resquestUrl, "UTF-8");
	}

	public static HttpsClient configure(String resquestUrl, String charset) throws Exception {
		
		URL url = new URL(URLencode(resquestUrl, charset));
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		if (conn instanceof HttpsURLConnection) {
			((HttpsURLConnection) conn).setSSLSocketFactory(sslContext.getSocketFactory());
			((HttpsURLConnection) conn).setHostnameVerifier(verifier);
		}
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setUseCaches(false);// no cache
		return new HttpsClient(conn, charset);
	}

	private static String URLencode(String resquestUrl, String charset) throws UnsupportedEncodingException {
		
		String[] split = resquestUrl.split("\\?");
		StringBuffer sb = new StringBuffer();
		sb.append(split[0]);
		if (split.length > 1) {
			sb.append("?");
			String[] params = split[1].split("&");
			for (String param : params) {
				String[] split2 = param.split("=");
				if (!sb.toString().endsWith("?")) {
					sb.append("&");
				}
				sb.append(split2[0] + "=");
				if (split2.length > 1) {
					sb.append(URLEncoder.encode(split2[1], charset));
				}
			}
		}
		System.out.println("requestUrl:" + sb.toString());
		return sb.toString();
	}
	
	public HttpsClient addRequestProperty(String key, String value) {
		
		conn.addRequestProperty(key, value);
		return this;
    }
	
	public String doPost(String content) throws Exception {
		
		InputStreamReader inputStreamReader;
		BufferedReader bufferedReader;
		StringBuffer buffer = new StringBuffer();
		
		conn.addRequestProperty("connection", "Keep-Alive");
		conn.setRequestMethod("POST");
		
		conn.connect();
		
		DataOutputStream out = new DataOutputStream(conn.getOutputStream());
		out.write(content.getBytes(charset));
		out.flush();
        out.close();
		InputStream inputStream = conn.getInputStream();
		inputStreamReader = new InputStreamReader(inputStream, charset);
		bufferedReader = new BufferedReader(inputStreamReader);
		String str = null;
		while ((str = bufferedReader.readLine()) != null) {
			buffer.append(str);
		}
		inputStream.close();

		conn.disconnect();
		
		return buffer.toString();
	}
}
